// Copyright (c) 2015-present, salesforce.com, inc. All rights reserved
// Licensed under BSD 3-Clause - see LICENSE.txt or git.io/sfdc-license

@import 'deprecate';

/**
 * @name base
 * @selector .slds-modal
 * @restrict section
 * @support dev-ready
 * @variant
 */
.slds-modal {
  opacity: 0;
  visibility: hidden;
  transition:
    transform $duration-quickly linear,
    opacity $duration-quickly linear;
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  z-index: ($z-index-modal + 1);

  /**
    * Modal title (optional)
    *
    * @selector .slds-modal__title
    * @restrict .slds-modal__header h1, .slds-modal__header h2, .slds-modal__header h3, .slds-modal__header h4, .slds-modal__header h5
    */
  .slds-modal__title {
    font-weight: var(--slds-c-modal-heading-font-weight, var(--sds-c-modal-heading-font-weight));
    font-size: var(--slds-c-modal-heading-font-size, var(--sds-c-modal-heading-font-size, $font-size-7));
    line-height: var(--slds-c-modal-heading-line-height, var(--sds-c-modal-heading-line-height, $line-height-heading));
  }
}

/**
  * Centers and sizes the modal horizontally and confines modal within viewport height
  *
  * @selector .slds-modal__container
  * @restrict .slds-modal div
  * @notes This should be nested immediately inside `.slds-modal` with nothing else nested on the same level.
  * @required
  */
.slds-modal__container {
  position: relative;
  transform: translate(0, 0);
  transition:
    transform $duration-quickly linear,
    opacity $duration-quickly linear;
  display: flex;
  flex-direction: column;
  justify-content: center;
  margin: 0 $spacing-x-large;
  height: 100%;
  padding: $square-icon-large-boundary 0 $square-icon-large-boundary-alt 0;
  border-radius: $border-radius-medium;

  @include mq-medium-min {
    margin: 0 auto;
    width: 50%;
    max-width: 40rem; // TODO: Tokenize
    min-width: 20rem; // TODO: Tokenize
  }
}

/**
  * Creates the Modal Header container.
  *
  * @selector .slds-modal__header
  * @restrict .slds-modal header
  * @notes This should be nested immediately inside `.slds-modal__container` as the first element.
  * @required
  */
.slds-modal__header {
  position: relative;
  border-top-right-radius: var(--slds-c-modal-radius-border, var(--sds-c-modal-radius-border, $border-radius-medium));
  border-top-left-radius: var(--slds-c-modal-radius-border, var(--sds-c-modal-radius-border, $border-radius-medium));
  border-bottom-width: var(--slds-c-modal-sizing-border, var(--sds-c-modal-sizing-border, $border-width-thick));
  border-bottom-style: solid;
  border-bottom-color: var(--slds-c-modal-color-border, var(--sds-c-modal-color-border, var(--slds-g-color-border-base-1, #{$color-border})));
  background-color: var(--slds-c-modal-header-color-background, var(--sds-c-modal-header-color-background, var(--slds-c-modal-color-background, var(--sds-c-modal-color-background, var(--slds-g-color-neutral-base-100, #{$color-background-alt})))));
  color: var(--slds-c-modal-header-text-color, var(--sds-c-modal-header-text-color, var(--sds-c-modal-text-color)));
  flex-shrink: 0;
  padding-top: var(--slds-c-modal-header-spacing-block-start, var(--slds-c-modal-header-spacing-blockstart, var(--sds-c-modal-header-spacing-block-start, $spacing-medium)));
  padding-right: var(--slds-c-modal-header-spacing-inline-end, var(--slds-c-modal-header-spacing-inlineend, var(--sds-c-modal-header-spacing-inline-end, $spacing-medium)));
  padding-bottom: var(--slds-c-modal-header-spacing-block-end, var(--slds-c-modal-header-spacing-blockend, var(--sds-c-modal-header-spacing-block-end, $spacing-medium)));
  padding-left: var(--slds-c-modal-header-spacing-inline-start, var(--slds-c-modal-header-spacing-inlinestart, var(--sds-c-modal-header-spacing-inline-start, $spacing-medium)));
  text-align: center;

  + .slds-modal__menu {
    border-top-right-radius: 0;
    border-top-left-radius: 0;
  }
}


/**
  * Headless modal styling
  *
  * @selector .slds-modal__content_headless
  * @restrict .slds-modal__content
  */
.slds-modal__content_headless,
.slds-modal__header_empty + .slds-modal__content,
.slds-modal__header--empty + .slds-modal__content {
  border-top-right-radius: var(--slds-c-modal-radius-border, var(--sds-c-modal-radius-border, $border-radius-medium));
  border-top-left-radius: var(--slds-c-modal-radius-border, var(--sds-c-modal-radius-border, $border-radius-medium));
}

/**
  * Creates the scrollable content area for the modal.
  *
  * @selector .slds-modal__content
  * @restrict .slds-modal div
  * @required
  */
.slds-modal__content {
  background-color: var(--slds-c-modal-content-color-background, var(--sds-c-modal-content-color-background, var(--slds-c-modal-color-background, var(--sds-c-modal-color-background, var(--slds-g-color-neutral-base-100, #{$color-background-alt})))));
  color: var(--slds-c-modal-content-text-color, var(--sds-c-modal-content-text-color, var(--slds-c-modal-text-color, var(--sds-c-modal-text-color))));
  overflow: hidden;
  overflow-y: auto;
}

/**
  * Footless modal styling
  *
  * @selector .slds-modal__content_footless
  * @restrict .slds-modal__content
  */
.slds-modal__content_footless,
.slds-modal__container > .slds-modal__content:last-child,
.slds-modal__content_has-hidden-footer {
  border-bottom-right-radius: var(--slds-c-modal-radius-border, var(--sds-c-modal-radius-border, $border-radius-medium));
  border-bottom-left-radius: var(--slds-c-modal-radius-border, var(--sds-c-modal-radius-border, $border-radius-medium));
  box-shadow: var(--slds-c-modal-shadow, var(--sds-c-modal-shadow, $shadow-drop-down));
}

/**
  * Creates the Modal Footer container.
  *
  * @selector .slds-modal__footer
  * @restrict .slds-modal footer
  * @notes This should be nested immediately inside `.slds-modal_container` and immediately after `.slds-modal__container`. Nothing should follow it. Note that by default, elements will be aligned to the right.
  * @required
  */
.slds-modal__footer {
  border-bottom-right-radius: var(--slds-c-modal-radius-border, var(--sds-c-modal-radius-border, $border-radius-medium));
  border-bottom-left-radius: var(--slds-c-modal-radius-border, var(--sds-c-modal-radius-border, $border-radius-medium));
  border-top-width: var(--slds-c-modal-sizing-border, var(--sds-c-modal-sizing-border, $border-width-thick));
  border-top-style: solid;
  border-top-color: var(--slds-c-modal-color-border, var(--sds-c-modal-color-border, var(--slds-g-color-border-base-1, #{$color-border})));
  background-color: var(--slds-c-modal-footer-color-background, var(--sds-c-modal-footer-color-background, var(--slds-c-modal-color-background, var(--sds-c-modal-color-background, var(--slds-g-color-neutral-base-95, #{$color-background})))));
  color: var(--slds-c-modal-footer-text-color, var(--sds-c-modal-footer-text-color, var(--slds-c-modal-text-color, var(--sds-c-modal-text-color))));
  flex-shrink: 0;
  padding-top: var(--slds-c-modal-footer-spacing-block-start, var(--slds-c-modal-footer-spacing-blockstart, var(--sds-c-modal-footer-spacing-block-start, $spacing-small)));
  padding-right: var(--slds-c-modal-footer-spacing-inline-end, var(--slds-c-modal-footer-spacing-inlineend, var(--sds-c-modal-footer-spacing-inline-end, $spacing-medium)));
  padding-bottom: var(--slds-c-modal-footer-spacing-block-end, var(--slds-c-modal-footer-spacing-blockend, var(--sds-c-modal-footer-spacing-block-end, $spacing-small)));
  padding-left: var(--slds-c-modal-footer-spacing-inline-start, var(--slds-c-modal-footer-spacing-inlinestart, var(--sds-c-modal-footer-spacing-inline-start, $spacing-medium)));
  text-align: right;
  box-shadow: var(--slds-c-modal-shadow, var(--sds-c-modal-shadow, $shadow-drop-down));

  .slds-button + .slds-button {
    margin-left: $spacing-x-small;
  }
}

/**
  * Makes buttons inside the footer spread to both left and right.
  *
  * @selector .slds-modal__footer_directional
  * @restrict .slds-modal__footer
  * @notes This is only needed when you have two buttons that indicate a back and forward navigation.
  * @modifier
  * @group direction
  */
.slds-modal__footer_directional .slds-button:first-child,
.slds-modal__footer--directional .slds-button:first-child {
  float: left;
}

/**
  * Positions the close button to the top right outside of the modal.
  *
  * @selector .slds-modal__close
  * @restrict .slds-modal button
  * @notes Either `.slds-modal__content` or `.slds-modal__menu` must be used. If you’re using this class, you do not need the other. This should be nested immediately inside `.slds-modal_container`.
  * @required
  */
.slds-modal__close {
  @include square($square-icon-medium-boundary);
  margin-left: auto;
  position: relative;
  bottom: $spacing-x-small;
  background-color: var(--slds-g-color-neutral-base-100, #{$palette-neutral-100});

  &:active {
    background-color: var(--slds-g-color-neutral-base-95, #{$palette-neutral-95});
    border: none;
  }

  // Interim fix released to handle non compliant custom modal implementations. W-16663862
  &.slds-button_icon-inverse, &.slds-button--icon-inverse, .slds-button_icon-inverse, .slds-button--icon-inverse {
    color: var(--slds-g-color-neutral-base-50,#747474);
    --slds-c-icon-color-foreground: var(--slds-g-color-neutral-base-50,#747474);
  }

  // Interim fix part 2 released to handle non compliant custom aura modal implementations. W-16940743
  &.slds-icon-utility-close, .slds-icon-utility-close {
    --slds-c-icon-color-foreground: var(--slds-g-color-neutral-base-50,#747474);
  }

  &:focus,
  &:focus-visible {
    box-shadow: var(--slds-g-shadow-inset-inverse-focus-1);
    outline: 0;
  }
}

@mixin backdrop {
  // Mixin created to not have to paste this again into the new class it's being renamed to (see below)
  @include duration-slowly;
  @include square(100%);
  opacity: 0;
  visibility: hidden;
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  background: var(--slds-c-backdrop-color-background, var(--sds-c-backdrop-color-background, var(--slds-s-backdrop-color-background, 
    var(--slds-g-color-neutral-10-opacity-50, #{$color-background-temp-modal-tint}))));
  z-index: $z-index-modal;

  /**
   * Allows the backdrop to be visible.
   *
   * @selector .slds-backdrop_open
   * @restrict .slds-backdrop
   * @notes Apply this class to a modal backdrop with JavaScript to make it visible.
   * @modifier
   * @required
   */
  &_open,
  &--open {
    visibility: visible;
    opacity: 1;
    transition: opacity $duration-slowly linear;
  }
}

/**
 * @summary Widens the modal to take more horizontal space than default
 * @name small
 * @selector .slds-modal_small
 * @restrict .slds-modal
 * @modifier
 * @group size
 */
.slds-modal_small {

  .slds-modal__container {
    @include mq-medium-min {
      width: 60%;
      max-width: 52.0625rem; // This value taken from welcome mat modal
      min-width: 40rem; // TODO: Tokenize
    }
  }
}

/**
 * @summary Widens the modal to take more horizontal space than small
 * @name medium
 * @selector .slds-modal_medium
 * @restrict .slds-modal
 * @modifier
 * @group size
 */
.slds-modal_medium {

  .slds-modal__container {
    @include mq-medium-min {
      width: 70%;
      max-width: 75rem;
      min-width: 40rem; // TODO: Tokenize
    }
  }
}

/**
 * @summary Widens the modal to take more horizontal space than large
 * @name large
 * @selector .slds-modal_large
 * @restrict .slds-modal
 * @modifier
 * @group size
 */
.slds-modal_large .slds-modal__container,
.slds-modal--large .slds-modal__container {
  @include mq-medium-min {
    width: 90%;
    max-width: none;
    min-width: 40rem; // TODO: Tokenize
  }
}

/**
 * @summary Makes the modal full screen in small viewports
 * @name full
 * @selector .slds-modal_full
 * @restrict .slds-modal
 * @modifier
 * @group size
 */
.slds-modal_full {

  // Behaves like large size when not in a small viewport
  .slds-modal__container {
    @include mq-medium-min {
      width: 90%;
      max-width: none;
      min-width: 40rem;
    }
  }

  // We use mq-small-max since modal was originally designed as desktop first;
  // This saves us from having to duplicate code for the full modifier.
  @include mq-small-max {
    // Account for iOS safe areas so our modal doesn't load underneath iOS elements.
    top: env(safe-area-inset-top, 0);
    // Override slds-modal's bottom: 0 so we can make the height dynamic.
    bottom: auto;
    // Viewport may be dynamic, e.g., iOS Safari toolbar hiding behavior, so we use dvh. Safe areas may not be required here.
    height: calc(100dvh - env(safe-area-inset-top) - env(safe-area-inset-bottom));

    .slds-modal__header {
      grid-area: header;
      border-top-left-radius: 0;
      border-top-right-radius: 0;
    }

    .slds-modal__container {
      width: 100%;
      max-width: none;
      min-width: 0;
      margin: 0;
      padding: $spacing-medium 0 0 0;
      // Only __content used to get background color, we want entire modal to get it since we're fullscreen
      background-color: var(--slds-c-modal-header-color-background, var(--slds-c-modal-color-background, var(--slds-g-color-neutral-base-100, #{$color-background-alt})));
      border-radius: 0;
      /* Establishes the main layout of the modal. Grid is defined by grid-template-areas
      which explicitly defines the grid and allows optional elements to be omitted like
      the header or footer. */
      display: grid;
      height: 100dvh;
      grid-template-rows: min-content min-content 1fr min-content;
      grid-template-areas:
        "close"
        "header"
        "content"
        "footer";
      grid-template-columns: minmax(0, 1fr);
    }

    /**
    * Footless modal styling
    */
    .slds-modal__content_footless,
    .slds-modal__container > .slds-modal__content:last-child,
    .slds-modal__content_has-hidden-footer {
      border-bottom-right-radius: 0;
      border-bottom-left-radius: 0;
      box-shadow: none;
    }

    .slds-modal__close {
      grid-area: close;
      right: $spacing-medium;

      // A few things going on here:
      // - We want to avoid a markup change for a single modifier so we reassign/override.
      // - Button icon doesn't have component level hooks (yet), so we don't include them here
      //   and we have to override the CSS property instead of reassign.
      // - States on button have a bug, they override instead of reassign hooks
      //   so the values of empty hooks default to initial values. In the case
      //   of background colors, the background will disappear (initial = transparent).
      --slds-c-button-color-background: var(--slds-g-color-neutral-base-100, #{$button-color-background-primary});
      --slds-c-button-color-background-active: var(--slds-g-color-neutral-base-100, #{$button-color-background-primary});
      color: var(--slds-g-color-neutral-base-50, #{$color-text-icon-default});
    }

    .slds-modal__close:hover,
    .slds-modal__:focus {
      color: $brand-accessible-active;
    }

    .slds-modal__content {
      grid-area: content;
    }

    .slds-modal__footer {
      grid-area: footer;
      border-bottom-right-radius: 0;
      border-bottom-left-radius: 0;
      box-shadow: none;
    }
  }

  /**
   * INTERNAL USE ONLY - SUBJECT TO CHANGE AND REMOVAL
   *
   * SLDS Blueprint <> LBC Parity Patch
   *
   * SLDS blueprints and LBC implementation are not 1:1. This patch is needed to
   * account for the differences introduced in the LBC implementation. Location
   * of this code would ideally live within the LBC component CSS module but
   * synthetic shadow and how LBC deconstructs the modal into individual components
   * makes this not feasible. Not ideal, but this is the best solution for now.
   * Selectors are scoped to lightning-* to avoid any potential outside conflicts.
   */
  lightning-modal,
  lightning-modal-header,
  lightning-modal-body,
  lightning-modal-footer {
      display: contents;
  }
}

/**
 * Creates the shaded backdrop used behind the modal.
 *
 * @selector .slds-backdrop
 * @restrict .slds-modal ~ div
 * @notes This should follow after the `.slds-modal` as an empty element.
 * @required
 */
.slds-backdrop {
  // new class
  @include backdrop;
}

/**
 * Allows the modal to be visible.
 *
 * @selector .slds-fade-in-open
 * @restrict .slds-modal
 * @notes Apply this class to a modal with JavaScript to make it visible.
 * @modifier
 * @group animation
 */
.slds-fade-in-open {
  opacity: 1;
  visibility: visible;
  transition: opacity $duration-quickly linear;

  .slds-modal__container-reset {
    opacity: 1;
    visibility: visible;
    transform: translate(0, 0);
  }
}

/**
 *
 *
 * @selector .slds-slide-up-open
 * @restrict .slds-modal
 * @modifier
 * @group animation
 */
.slds-slide-up-open {
  opacity: 1;
  visibility: visible;
  transform: translate(0, 0);
  transition:
    opacity $duration-quickly linear,
    transform $duration-promptly linear;

  .slds-modal__container-reset {
    opacity: 0;
    visibility: hidden;
    transform: translate(0, $spacing-medium);
    transition:
      opacity $duration-promptly linear,
      transform $duration-promptly linear;
  }
}

/**
 *
 *
 * @selector .slds-slide-up-saving
 * @restrict .slds-modal
 * @modifier
 * @group animation
 */
.slds-slide-up-saving {
  opacity: 1;
  visibility: visible;
  transform: translate(0, -$spacing-medium);
}

/**
 *
 *
 * @selector .slds-slide-down-cancel
 * @restrict .slds-modal
 * @modifier
 * @group animation
 */
.slds-slide-down-cancel {
  opacity: 1;
  visibility: visible;
  transform: translate(0, $spacing-medium);
}
